﻿#region Copyrights Notice
//©2010 Microsoft Corporation. All rights reserved.
#endregion

#region usings
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.InformationSecurity.CISF.Common.Utilities;
using System.IO;
using System.Security.AccessControl;
#endregion

namespace CISFAppDeployer
{
    public class Installer
    {
        #region Content Management

        private Installer()
        {

        }
        /// <summary>
        /// Creates a folder in the directory path provided.
        /// </summary>
        /// <param name="directoryPath"></param>
        /// <param name="folderName"></param>
        /// <returns></returns>
        public static bool AddAppDirectory(string directoryPath, string folderName)
        {
            Logger.WriteLine("    Creating application (destination) folder in the Portal...", "");
            try
            {
                //Create Directory value
                string destinationFolder = directoryPath + folderName;

                // Create a new DirectoryInfo object.
                DirectoryInfo dInfo = new DirectoryInfo(destinationFolder);

                if (!dInfo.Exists)
                {
                    //now create the folder
                    dInfo.Create();
                }
            }
            catch
            {
                Logger.WriteLine("Error creating the application folder...", "Error");
                return false;
            }
            return true;
        }

        /// <summary>
        /// Copies files/folders from source location to destination location
        /// </summary>
        /// <param name="directoryPath"></param>
        /// <param name="folderName"></param>
        /// <returns></returns>
        public static bool CopyAppDirectory(string sourceFolder, string destinationFolder, bool overwrite)
        {
            try
            {

                // Create a new DirectoryInfo object.
                DirectoryInfo dInfo = new DirectoryInfo(destinationFolder);
                DirectoryInfo sInfo = new DirectoryInfo(sourceFolder);

                if (!dInfo.Exists)
                {
                    dInfo.Create();
                }
                //now copy all files from source to destination
                foreach (FileInfo file in sInfo.GetFiles())
                {
                    file.CopyTo(Path.Combine(dInfo.FullName, file.Name), overwrite);
                }

                //now create directory and loop thru the files
                foreach (DirectoryInfo dir in sInfo.GetDirectories())
                {
                    if (!dir.Exists)
                    {
                        dir.Create();
                    }
                    CopyAppDirectory(dir.FullName, Path.Combine(dInfo.FullName, dir.Name), overwrite);
                }
            }
            catch
            {
                Logger.WriteLine("Error copying the application files...", "Error");
                return false;
            }
            return true;
        }

        /// <summary>
        /// Removes the application folder in the directory path provided.
        /// </summary>
        /// <param name="directoryPath"></param>
        /// <param name="folderName"></param>
        /// <returns></returns>
        public static bool RemoveAppDirectory(string directoryPath, string applicationName, string archiveFolder)
        {
            try
            {
                //first backup the application folder
                string format = "MM-dd-yy HH.mm.ss";
                string sourceDirectory = String.Empty;
                sourceDirectory = directoryPath + applicationName;

                string destDirectory = String.Empty;
                destDirectory = archiveFolder + applicationName + " " + DateTime.Now.ToString(format) ;

                //move the files to archive
                Logger.WriteLine("    Archiving application folder to: " + destDirectory, "");
                CopyAppDirectory(sourceDirectory, destDirectory, true);

                //then delete the application folder
                Logger.WriteLine("    Deleting application folder...", "");
                FileSystemInfo fsDesInfo = new DirectoryInfo(sourceDirectory);
                DeleteApplication(fsDesInfo);
            }
            catch
            {
                Logger.WriteLine("Error removing the application contents", "Error");
                return false;
            }
            return true;
        }

        /// <summary>
        /// Deletes the applicaiton source code after removing the read only flag from the files
        /// </summary>
        /// <param name="destFilesys"></param>
        private static void DeleteApplication(FileSystemInfo destFilesys)
        {
            destFilesys.Attributes = FileAttributes.Normal;
            var di = destFilesys as DirectoryInfo;

            if (di != null)
            {
                foreach (var dirInfo in di.GetFileSystemInfos())
                    DeleteApplication(dirInfo);
            }
            destFilesys.Delete();
        }

        /// <summary>
        /// Updates Web.Config and Sitemap files as per the Portal deployment requirements in the directory provided
        /// </summary>
        /// <param name="directoryPath"></param>
        /// <param name="folderName"></param>
        /// <returns>bool</returns>
        public static bool UpdateNewAppSettings(string appName, string appFolderName, string directoryPath)
        {
            //Update Web.Config and Sitemap files as per the Portal deployment requirements
            Logger.WriteLine("    Updating web.config file...", "");
            try
            {
                WebConfigManager myconfig = new WebConfigManager();
                myconfig.docName = directoryPath + "\\web.config";
                myconfig.SetValue("appSettings", "ApplicationName", appName);
                myconfig.SetValue("appSettings", "ApplicationFolderName", appFolderName);
            }
            catch
            {
                Logger.WriteLine("Error updating web.config...", "Error");
                return false;
            }

            Logger.WriteLine("    Updating appweb.sitemap file...", "");
            try
            {
                //Updating sitemap with Appropriate application links --> "/Applications/AppName/XYZ"
                SiteMapManager mysitemap = new SiteMapManager();
                mysitemap.docName = directoryPath + "\\appweb.sitemap";
                mysitemap.Deployer_UpdateApplicationSitemapLinks(appName, appFolderName);
            }
            catch
            {
                Logger.WriteLine("Error updating appweb.sitemap...", "Error");
                return false;
            }
            //finally
            return true;
        }

        /// <summary>
        /// Updates Portal Web.sitemap with application sitemap link
        /// </summary>
        /// <param name="portalRootFolder"></param>
        /// <param name="appFolderName"></param>
        /// <returns>bool</returns>
        public static bool UpdatePortalSitemap(string portalRootFolder, string appFolderName, bool installFlag)
        {
            Logger.WriteLine("    Updating portal web.sitemap...", "");
            try
            {
                //Updating portal sitemap with application sitemap link
                SiteMapManager mysitemap = new SiteMapManager();
                mysitemap.docName = portalRootFolder + "web.sitemap";
                
                //update portal sitemap based on install or uninstall flag
                if (installFlag)
                {
                    mysitemap.SetSiteMapNode("~/Applications/" + appFolderName + "/AppWeb.Sitemap");
                }
                else
                {
                    mysitemap.RemoveSiteMapNode("~/Applications/" + appFolderName + "/AppWeb.Sitemap");
                }
            }
            catch
            {
                Logger.WriteLine("Error updating appweb.sitemap...", "Error");
                return false;
            }
            //finally
            return true;
        }

        #endregion
    }
}
